/**
 * 模块加载器实现
 * 负责动态加载、验证和执行模块
 */
import axios from 'axios'
import type { 
  IModuleLoader, 
  DynamicModule, 
  ModuleLoadOptions, 
  ModuleUnloadOptions, 
  ModuleValidationResult,
  ModuleLoadState
} from './types'
import { moduleStorage } from './ModuleStorage'

export class ModuleLoader implements IModuleLoader {
  private loadingModules = new Map<string, Promise<any>>()
  private loadedModules = new Map<string, any>()
  private validationCache = new Map<string, ModuleValidationResult>()

  /**
   * 加载模块
   */
  async load(module: DynamicModule, options: ModuleLoadOptions = {}): Promise<any> {
    const {
      force = false,
      timeout = 30000,
      maxRetries = 3,
      loadDependencies = true,
      loader
    } = options

    const cacheKey = `module:${module.id}`
    
    // 检查是否已加载
    if (!force && this.loadedModules.has(module.id)) {
      return this.loadedModules.get(module.id)
    }

    // 检查是否正在加载
    if (this.loadingModules.has(module.id)) {
      return this.loadingModules.get(module.id)
    }

    // 创建加载任务
    const loadTask = this.performLoad(module, {
      force,
      timeout,
      maxRetries,
      loadDependencies,
      loader
    })

    this.loadingModules.set(module.id, loadTask)

    try {
      const result = await loadTask
      this.loadedModules.set(module.id, result)
      return result
    } catch (error) {
      this.loadingModules.delete(module.id)
      throw error
    }
  }

  /**
   * 卸载模块
   */
  async unload(module: DynamicModule, options: ModuleUnloadOptions = {}): Promise<void> {
    const {
      force = false,
      clearCache = true,
      unloadDependencies = true
    } = options

    // 从加载的模块中移除
    this.loadedModules.delete(module.id)
    this.loadingModules.delete(module.id)

    // 清理缓存
    if (clearCache) {
      await moduleStorage.delete(`module:${module.id}`)
      await moduleStorage.delete(`module:${module.id}:files`)
      this.validationCache.delete(module.id)
    }

    // 如果有依赖，也卸载依赖
    if (unloadDependencies && module.dependencies) {
      for (const depId of module.dependencies) {
        // 这里需要递归卸载依赖，但需要更复杂的逻辑来避免循环依赖
        // 简化版本暂时不实现
      }
    }

    console.log(`[ModuleLoader] Module ${module.id} unloaded`)
  }

  /**
   * 验证模块
   */
  async validate(module: DynamicModule): Promise<ModuleValidationResult> {
    // 检查验证缓存
    if (this.validationCache.has(module.id)) {
      return this.validationCache.get(module.id)!
    }

    const errors: string[] = []
    const warnings: string[] = []

    // 基本字段验证
    if (!module.id || typeof module.id !== 'string') {
      errors.push('Module ID is required and must be a string')
    }

    if (!module.name || typeof module.name !== 'string') {
      errors.push('Module name is required and must be a string')
    }

    if (!module.version || typeof module.version !== 'string') {
      errors.push('Module version is required and must be a string')
    }

    if (!module.entry || typeof module.entry !== 'string') {
      errors.push('Module entry point is required and must be a string')
    }

    // 版本格式验证
    if (module.version && !this.isValidVersion(module.version)) {
      warnings.push('Module version should follow semantic versioning (e.g., 1.0.0)')
    }

    // 依赖验证
    if (module.dependencies) {
      for (const dep of module.dependencies) {
        if (!dep || typeof dep !== 'string') {
          errors.push(`Invalid dependency: ${dep}`)
        }
      }
    }

    // 权限验证
    if (module.permissions) {
      for (const perm of module.permissions) {
        if (!perm || typeof perm !== 'string') {
          warnings.push(`Invalid permission format: ${perm}`)
        }
      }
    }

    // 配置架构验证
    if (module.config_schema) {
      try {
        JSON.parse(module.config_schema)
      } catch (error) {
        errors.push('Invalid JSON schema in config_schema')
      }
    }

    const result: ModuleValidationResult = {
      isValid: errors.length === 0,
      errors,
      warnings
    }

    // 缓存验证结果
    this.validationCache.set(module.id, result)

    return result
  }

  /**
   * 获取模块文件
   */
  async getModuleFiles(moduleId: string): Promise<any> {
    const cacheKey = `module:${moduleId}:files`
    
    // 尝试从缓存获取
    const cached = await moduleStorage.get(cacheKey)
    if (cached) {
      return cached
    }

    try {
      // 从后端API获取模块文件
      const response = await axios.get(`/api/widgets/${moduleId}/files`)
      const files = response.data

      // 缓存文件内容
      await moduleStorage.save(cacheKey, files, 10 * 60 * 1000) // 10分钟缓存

      return files
    } catch (error) {
      console.error(`[ModuleLoader] Failed to fetch module files for ${moduleId}:`, error)
      throw new Error(`Failed to fetch module files: ${error instanceof Error ? error.message : 'Unknown error'}`)
    }
  }

  /**
   * 执行实际的模块加载
   */
  private async performLoad(
    module: DynamicModule, 
    options: ModuleLoadOptions
  ): Promise<any> {
    const {
      timeout = 30000,
      maxRetries = 3,
      loadDependencies = true,
      loader
    } = options

    let retryCount = 0
    let lastError: Error | null = null

    while (retryCount <= maxRetries) {
      try {
        // 验证模块
        const validation = await this.validate(module)
        if (!validation.isValid) {
          throw new Error(`Module validation failed: ${validation.errors.join(', ')}`)
        }

        // 加载依赖
        if (loadDependencies && module.dependencies) {
          await this.loadDependencies(module.dependencies)
        }

        // 使用自定义加载器或默认加载器
        if (loader) {
          return await loader(module)
        } else {
          return await this.defaultLoadModule(module, timeout)
        }

      } catch (error) {
        lastError = error instanceof Error ? error : new Error('Unknown error')
        retryCount++

        if (retryCount <= maxRetries) {
          console.warn(`[ModuleLoader] Retry ${retryCount}/${maxRetries} for module ${module.id}`)
          await this.delay(1000 * retryCount) // 指数退避
        } else {
          break
        }
      }
    }

    throw lastError || new Error('Module loading failed after maximum retries')
  }

  /**
   * 默认模块加载方法
   */
  private async defaultLoadModule(module: DynamicModule, timeout: number): Promise<any> {
    // 创建超时Promise
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => reject(new Error(`Module loading timeout for ${module.id}`)), timeout)
    })

    // 创建加载Promise
    const loadPromise = this.createModuleComponent(module)

    // 竞争执行
    return Promise.race([loadPromise, timeoutPromise])
  }

  /**
   * 创建模块组件
   */
  private async createModuleComponent(module: DynamicModule): Promise<any> {
    try {
      // 获取模块文件
      const files = await this.getModuleFiles(module.id)

      if (!files || !files.frontend_files) {
        throw new Error('No frontend files found for module')
      }

      // 生成动态组件代码
      const componentCode = this.generateComponentCode(module, files)

      // 创建Blob URL
      const blob = new Blob([componentCode], { type: 'text/javascript' })
      const url = URL.createObjectURL(blob)

      try {
        // 动态导入组件
        const moduleExports = await import(/* @vite-ignore */ url)
        
        // 获取默认导出或具名导出
        const component = moduleExports.default || moduleExports
        
        if (!component) {
          throw new Error('Module does not export a valid component')
        }

        return component
      } finally {
        URL.revokeObjectURL(url)
      }

    } catch (error) {
      console.error(`[ModuleLoader] Failed to create component for module ${module.id}:`, error)
      throw error
    }
  }

  /**
   * 生成组件代码
   */
  private generateComponentCode(module: DynamicModule, files: any): string {
    const { frontend_files } = files
    
    // 这里需要根据实际的文件结构生成组件代码
    // 简化版本：假设前端文件包含Vue组件代码
    const mainComponent = frontend_files.find((file: any) => file.name === module.entry)
    
    if (!mainComponent) {
      throw new Error(`Entry file ${module.entry} not found in module files`)
    }

    // 生成包装后的组件代码
    return `
      import { defineComponent, h, ref, onMounted, onUnmounted } from 'vue'
      
      const moduleComponent = defineComponent({
        name: '${module.name}',
        props: {
          config: {
            type: Object,
            default: () => ({})
          }
        },
        setup(props, { emit }) {
          const loading = ref(false)
          const error = ref(null)
          const data = ref(null)
          
          const moduleConfig = ref(props.config || {})
          
          // 模块生命周期
          onMounted(() => {
            console.log('[${module.name}] Module mounted')
            emit('module:mounted', moduleConfig.value)
          })
          
          onUnmounted(() => {
            console.log('[${module.name}] Module unmounted')
            emit('module:unmounted')
          })
          
          // 模块方法
          const updateConfig = (newConfig) => {
            moduleConfig.value = { ...moduleConfig.value, ...newConfig }
            emit('module:config-updated', moduleConfig.value)
          }
          
          const refresh = async () => {
            loading.value = true
            try {
              // 这里可以添加模块特定的刷新逻辑
              emit('module:refreshed')
            } catch (err) {
              error.value = err
              emit('module:error', err)
            } finally {
              loading.value = false
            }
          }
          
          return () => {
            // 这里渲染实际的模块内容
            // 简化版本：显示模块信息
            return h('div', {
              class: 'dynamic-module',
              style: {
                padding: '20px',
                border: '1px solid #ddd',
                borderRadius: '8px'
              }
            }, [
              h('h3', { style: { margin: '0 0 10px 0' } }, '${module.name}'),
              h('p', { style: { margin: '0 0 10px 0', color: '#666' } }, '${module.description}'),
              h('div', { style: { fontSize: '12px', color: '#999' } }, [
                'Version: ${module.version}',
                h('br'),
                'Category: ${module.category}'
              ])
            ])
          }
        }
      })
      
      export default moduleComponent
    `
  }

  /**
   * 加载模块依赖
   */
  private async loadDependencies(dependencies: string[]): Promise<void> {
    // 这里需要实现依赖加载逻辑
    // 简化版本：假设依赖已经预加载或通过其他方式管理
    for (const depId of dependencies) {
      console.log(`[ModuleLoader] Loading dependency: ${depId}`)
      // 实际实现中需要递归加载依赖
    }
  }

  /**
   * 验证版本格式
   */
  private isValidVersion(version: string): boolean {
    const versionRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9-]+)?(\+[a-zA-Z0-9-]+)?$/
    return versionRegex.test(version)
  }

  /**
   * 延迟函数
   */
  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms))
  }

  /**
   * 获取加载状态
   */
  getLoadState(moduleId: string): ModuleLoadState | undefined {
    if (this.loadedModules.has(moduleId)) {
      return {
        id: moduleId,
        status: 'loaded',
        component: this.loadedModules.get(moduleId)
      }
    }
    
    if (this.loadingModules.has(moduleId)) {
      return {
        id: moduleId,
        status: 'loading'
      }
    }
    
    return undefined
  }

  /**
   * 获取所有已加载的模块
   */
  getLoadedModules(): string[] {
    return Array.from(this.loadedModules.keys())
  }

  /**
   * 检查模块是否已加载
   */
  isLoaded(moduleId: string): boolean {
    return this.loadedModules.has(moduleId)
  }

  /**
   * 清空所有加载的模块
   */
  async clearAll(): Promise<void> {
    const loadedIds = this.getLoadedModules()
    for (const moduleId of loadedIds) {
      try {
        await this.unload({ id: moduleId } as DynamicModule, { clearCache: true })
      } catch (error) {
        console.error(`[ModuleLoader] Error unloading module ${moduleId}:`, error)
      }
    }
    this.loadedModules.clear()
    this.loadingModules.clear()
    this.validationCache.clear()
  }
}

// 创建全局加载器实例
export const moduleLoader = new ModuleLoader()
